﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Controls;

namespace NB_Controller_Test
{
    public class SendRecvData
    {
        public Byte[] byData;
        public int nDataLen;
        public IntPtr connId;
    }

    public class UdpDataSndRecv : INetLinkDataRcvProc
    {
        public delegate void DeleRecvMsgProc(object obj, Byte byType);

        private UserControl _control;
        private NetLink netLink;
        private DeleRecvMsgProc delRecvMsgProc;

        public ConcurrentQueue<SendRecvData> sendList = new ConcurrentQueue<SendRecvData>();
        //public ConcurrentQueue<SendData> recvList = new ConcurrentQueue<SendData>();

        private bool exitThrd = false;
        //private Thread recvThrd = null;
        private Thread sendThrd = null;


        public void Init()
        {
            //if (recvThrd != null)
            //{
            //    recvThrd.Abort();
            //}
            //recvThrd = new Thread(RecvThreadFunc);
            //recvThrd.IsBackground = true;
            //recvThrd.Start();

            if (sendThrd != null)
            {
                sendThrd.Abort();
            }
            sendThrd = new Thread(SendThreadFunc);
            sendThrd.Priority = ThreadPriority.Lowest;
            sendThrd.IsBackground = true;
            sendThrd.Start();
        }

        public void Exit()
        {
            exitThrd = true;
        }

        public void AddSendMsg(byte[] data, int dataLen, IntPtr connId)
        {
            //lock (objLock)
            {
                SendRecvData sndData = new SendRecvData();
                sndData.byData = new byte[data.Length];
                Array.Copy(data, sndData.byData, data.Length);
                sndData.nDataLen = dataLen;
                sndData.connId = connId;
                sendList.Enqueue(sndData);
            }
        }

        //public void AddRecvMsg(SendData data)
        //{
        //    //lock (objLock)
        //    {
        //        sendList.Enqueue(data);
        //    }
        //}

        //private void RecvThreadFunc()
        //{
        //    while (!exitThrd)
        //    {
        //        //休眠1MS，其实是15MS左右
        //        Thread.Sleep(15);

        //        try
        //        {

        //        }
        //        catch (Exception /*ex*/)
        //        {

        //        }

        //    }//while
        //}

        private void SendThreadFunc()
        {
            while (!exitThrd)
            {
                //休眠1MS，其实是15MS左右
                Thread.Sleep(15);

                try
                {
                    //提取第一个数据，抛给UI
                    //lock (objLock)
                    {
                        SendRecvData data;
                        bool bOK = sendList.TryDequeue(out data);
                        if (data != null)
                            SendMsgData(data);
                    }
                }
                catch (Exception /*ex*/)
                {

                }

            }//while
        }

        private bool SendMsgData(SendRecvData data)
        {
            string strMsg = GlobalFun.ByteArrayToHexString(data.byData, data.nDataLen, "_");
            System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss fff ") + " [Send] " + strMsg);

            if (data.connId == IntPtr.Zero)
            {
                //广播
                netLink.SendMsgBroadCast(data.byData, 0, data.nDataLen);
            }
            else
            {
                //单播
                netLink.SendMsg(data.byData, 0, data.nDataLen, data.connId);
            }

            //故意将发送的内容打印到接收界面
            OnDataRecv(data.byData, data.nDataLen, data.connId, 1);
            return true;
        }

        private static UdpDataSndRecv udpDataRecv;
        static public UdpDataSndRecv GetUdpDataRecv(UserControl control)
        {
            if (udpDataRecv == null)
            {
                udpDataRecv = new UdpDataSndRecv(control);
            }
            return udpDataRecv;
        }

        private UdpDataSndRecv(UserControl control)
        {
            _control = control;
            netLink = NetLink.GetNetLink();
            netLink.RegisterDataRcvProc(this);

            Init();
        }

        public void RegisterRecvMsgProc(DeleRecvMsgProc proc)
        {
            delRecvMsgProc = proc;
        }

        public bool SendMsgData(byte[] data, int dataLen, IntPtr connId)
        {
            string strMsg = GlobalFun.ByteArrayToHexString(data, dataLen, "_");
            System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss fff ") + " [Send] " + strMsg);

            if (connId == IntPtr.Zero)
            {
                //广播
                netLink.SendMsgBroadCast(data, 0, dataLen);
            }
            else
            {
                //单播
                netLink.SendMsg(data, 0, dataLen, connId);
            }

            //故意将发送的内容打印到接收界面
            OnDataRecv(data, dataLen, connId, 1);
            return true;
        }

        public void OnDataRecv(byte[] data, int dataLen, IntPtr connId, Byte byType)
        {
            SendRecvData recvData = new SendRecvData();
            recvData.byData = data;
            recvData.nDataLen = dataLen;
            recvData.connId = connId;

            //MainWindow mainWnd = App.Current.MainWindow as MainWindow;
            if (_control != null)
            {
                _control.Dispatcher.BeginInvoke(delRecvMsgProc, recvData, byType);
            }

            //delRecvMsgProc(recvData, byType);
        }
    }
}
